<template>
  <div class="log-test-container">
    <el-card class="header-card">
      <template #header>
        <div class="card-header">
          <span class="title">
            <el-icon><Operation /></el-icon>
            日志测试工具
          </span>
          <span class="subtitle">快速生成各种类型的测试日志</span>
        </div>
      </template>

      <el-alert
        title="说明"
        type="info"
        :closable="false"
        show-icon
      >
        <p>此工具可以快速生成各种类型的日志，用于测试日志分析平台的功能</p>
        <p>生成的日志会通过Netty网络协议发送到日志分析服务，可在"网络日志接收"页面查看</p>
      </el-alert>
    </el-card>

    <!-- 批量生成 -->
    <el-card class="batch-card">
      <template #header>
        <div class="card-header">
          <span class="title">
            <el-icon><DocumentCopy /></el-icon>
            批量生成日志
          </span>
        </div>
      </template>

      <el-row :gutter="20" align="middle">
        <el-col :span="8">
          <el-input-number
            v-model="batchCount"
            :min="1"
            :max="1000"
            :step="10"
            style="width: 100%"
          />
        </el-col>
        <el-col :span="8">
          <el-button
            type="primary"
            :loading="batchLoading"
            @click="handleBatchGenerate"
            style="width: 100%"
          >
            <el-icon><Promotion /></el-icon>
            生成 {{ batchCount }} 条混合日志
          </el-button>
        </el-col>
        <el-col :span="8">
          <el-tag effect="dark" size="large">
            已生成: {{ totalGenerated }} 条
          </el-tag>
        </el-col>
      </el-row>
    </el-card>

    <!-- 测试场景 -->
    <el-card class="scenarios-card">
      <template #header>
        <div class="card-header">
          <span class="title">
            <el-icon><List /></el-icon>
            测试场景
          </span>
        </div>
      </template>

      <el-row :gutter="20">
        <el-col
          v-for="scenario in scenarios"
          :key="scenario.key"
          :xs="24"
          :sm="12"
          :md="8"
          :lg="6"
        >
          <el-card
            class="scenario-card"
            :class="scenario.type"
            shadow="hover"
          >
            <div class="scenario-content">
              <div class="scenario-header">
                <el-icon :size="32" :class="scenario.type">
                  <component :is="scenario.icon" />
                </el-icon>
                <el-tag :type="scenario.tagType" size="small">
                  {{ scenario.level }}
                </el-tag>
              </div>
              <h3>{{ scenario.title }}</h3>
              <p>{{ scenario.description }}</p>
              <el-button
                :type="scenario.buttonType"
                :loading="scenario.loading"
                @click="handleGenerate(scenario)"
                style="width: 100%"
              >
                生成日志
              </el-button>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </el-card>

    <!-- 实时日志输出 -->
    <el-card class="log-output-card">
      <template #header>
        <div class="card-header">
          <span class="title">
            <el-icon><Monitor /></el-icon>
            实时日志输出
          </span>
          <el-button
            size="small"
            @click="clearLogs"
          >
            <el-icon><Delete /></el-icon>
            清空
          </el-button>
        </div>
      </template>

      <div class="log-output" ref="logOutput">
        <div
          v-for="(log, index) in logs"
          :key="index"
          class="log-item"
          :class="log.type"
        >
          <span class="log-time">{{ log.time }}</span>
          <span class="log-type">{{ log.type }}</span>
          <span class="log-message">{{ log.message }}</span>
        </div>
        <div v-if="logs.length === 0" class="no-logs">
          暂无日志输出，点击上方按钮生成测试日志
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import {
  Operation,
  DocumentCopy,
  List,
  Monitor,
  Delete,
  Promotion,
  SuccessFilled,
  WarningFilled,
  CircleCloseFilled,
  InfoFilled,
  Connection,
  User,
  Document,
  ShoppingCart,
  Connection as NetworkIcon
} from '@element-plus/icons-vue'
import * as testApi from '@/api/test'

// 批量生成
const batchCount = ref(50)
const batchLoading = ref(false)
const totalGenerated = ref(0)

// 实时日志
const logs = ref([])
const logOutput = ref(null)

// 测试场景配置
const scenarios = reactive([
  {
    key: 'normal',
    title: '正常访问',
    description: '模拟正常的业务处理流程',
    icon: SuccessFilled,
    type: 'success',
    level: 'INFO',
    tagType: 'success',
    buttonType: 'success',
    loading: false,
    api: testApi.generateNormal
  },
  {
    key: 'slowDb',
    title: '数据库慢查询',
    description: '模拟数据库查询响应缓慢',
    icon: WarningFilled,
    type: 'warning',
    level: 'WARN',
    tagType: 'warning',
    buttonType: 'warning',
    loading: false,
    api: testApi.generateSlowDb
  },
  {
    key: 'nullPointer',
    title: '空指针异常',
    description: '模拟空指针异常错误',
    icon: CircleCloseFilled,
    type: 'error',
    level: 'ERROR',
    tagType: 'danger',
    buttonType: 'danger',
    loading: false,
    api: testApi.generateNullPointer
  },
  {
    key: 'dbConnection',
    title: '数据库连接失败',
    description: '模拟数据库无法连接',
    icon: CircleCloseFilled,
    type: 'error',
    level: 'ERROR',
    tagType: 'danger',
    buttonType: 'danger',
    loading: false,
    api: testApi.generateDbConnectionError
  },
  {
    key: 'networkTimeout',
    title: '网络超时',
    description: '模拟外部API调用超时',
    icon: NetworkIcon,
    type: 'error',
    level: 'ERROR',
    tagType: 'danger',
    buttonType: 'danger',
    loading: false,
    api: testApi.generateNetworkTimeout
  },
  {
    key: 'memoryWarning',
    title: '内存警告',
    description: '模拟内存使用率过高',
    icon: WarningFilled,
    type: 'warning',
    level: 'WARN',
    tagType: 'warning',
    buttonType: 'warning',
    loading: false,
    api: testApi.generateMemoryWarning
  },
  {
    key: 'authFailed',
    title: '认证失败',
    description: '模拟用户认证失败',
    icon: User,
    type: 'warning',
    level: 'WARN',
    tagType: 'warning',
    buttonType: 'warning',
    loading: false,
    api: testApi.generateAuthFailed
  },
  {
    key: 'concurrentAccess',
    title: '高并发访问',
    description: '模拟系统高并发情况',
    icon: Connection,
    type: 'info',
    level: 'INFO',
    tagType: '',
    buttonType: 'info',
    loading: false,
    api: testApi.generateConcurrentAccess
  },
  {
    key: 'fileOperation',
    title: '文件操作失败',
    description: '模拟文件读写错误',
    icon: Document,
    type: 'error',
    level: 'ERROR',
    tagType: 'danger',
    buttonType: 'danger',
    loading: false,
    api: testApi.generateFileOperationError
  },
  {
    key: 'businessError',
    title: '业务逻辑错误',
    description: '模拟业务校验失败',
    icon: ShoppingCart,
    type: 'warning',
    level: 'WARN',
    tagType: 'warning',
    buttonType: 'warning',
    loading: false,
    api: testApi.generateBusinessError
  }
])

// 生成单个场景日志
const handleGenerate = async (scenario) => {
  scenario.loading = true
  addLog('info', `正在生成 ${scenario.title} 日志...`)
  
  try {
    const res = await scenario.api()
    addLog('success', `✓ ${scenario.title} 日志生成成功`)
    totalGenerated.value++
    ElMessage.success('日志生成成功')
  } catch (error) {
    addLog('error', `✗ ${scenario.title} 日志生成失败: ${error.message}`)
    ElMessage.error('日志生成失败')
  } finally {
    scenario.loading = false
  }
}

// 批量生成日志
const handleBatchGenerate = async () => {
  batchLoading.value = true
  addLog('info', `开始批量生成 ${batchCount.value} 条日志...`)
  
  try {
    const res = await testApi.generateBatchLogs(batchCount.value)
    addLog('success', `✓ 成功生成 ${batchCount.value} 条混合日志`)
    totalGenerated.value += batchCount.value
    ElMessage.success(`成功生成 ${batchCount.value} 条日志`)
  } catch (error) {
    addLog('error', `✗ 批量生成失败: ${error.message}`)
    ElMessage.error('批量生成失败')
  } finally {
    batchLoading.value = false
  }
}

// 添加日志到输出窗口
const addLog = (type, message) => {
  const now = new Date()
  const time = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`
  
  logs.value.unshift({
    type,
    time,
    message
  })
  
  // 最多保留100条日志
  if (logs.value.length > 100) {
    logs.value.pop()
  }
}

// 清空日志
const clearLogs = () => {
  logs.value = []
  ElMessage.info('日志已清空')
}
</script>

<style scoped lang="scss">
.log-test-container {
  padding: 20px;

  .header-card {
    margin-bottom: 20px;

    .card-header {
      display: flex;
      flex-direction: column;
      gap: 8px;

      .title {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 18px;
        font-weight: bold;
        color: #303133;
      }

      .subtitle {
        font-size: 14px;
        color: #909399;
      }
    }

    :deep(.el-alert) {
      p {
        margin: 5px 0;
        line-height: 1.8;
      }
    }
  }

  .batch-card {
    margin-bottom: 20px;

    .card-header {
      .title {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 16px;
        font-weight: bold;
      }
    }
  }

  .scenarios-card {
    margin-bottom: 20px;

    .card-header {
      .title {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 16px;
        font-weight: bold;
      }
    }

    .el-row {
      margin-top: 10px;
    }

    .scenario-card {
      margin-bottom: 20px;
      height: 240px;
      transition: all 0.3s;
      border-left: 4px solid transparent;

      &.success {
        border-left-color: #67c23a;
      }

      &.warning {
        border-left-color: #e6a23c;
      }

      &.error {
        border-left-color: #f56c6c;
      }

      &.info {
        border-left-color: #409eff;
      }

      &:hover {
        transform: translateY(-5px);
      }

      .scenario-content {
        display: flex;
        flex-direction: column;
        height: 100%;

        .scenario-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 15px;

          .el-icon {
            &.success {
              color: #67c23a;
            }

            &.warning {
              color: #e6a23c;
            }

            &.error {
              color: #f56c6c;
            }

            &.info {
              color: #409eff;
            }
          }
        }

        h3 {
          margin: 0 0 10px 0;
          font-size: 16px;
          color: #303133;
        }

        p {
          flex: 1;
          margin: 0 0 15px 0;
          font-size: 14px;
          color: #606266;
          line-height: 1.6;
        }
      }
    }
  }

  .log-output-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .title {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 16px;
        font-weight: bold;
      }
    }

    .log-output {
      height: 400px;
      overflow-y: auto;
      background: #1e1e1e;
      border-radius: 4px;
      padding: 15px;
      font-family: 'Courier New', monospace;
      font-size: 13px;

      .log-item {
        display: flex;
        gap: 12px;
        padding: 6px 0;
        border-bottom: 1px solid #333;

        &:last-child {
          border-bottom: none;
        }

        .log-time {
          color: #858585;
          min-width: 65px;
        }

        .log-type {
          min-width: 60px;
          font-weight: bold;
        }

        .log-message {
          flex: 1;
          word-break: break-all;
        }

        &.success {
          .log-type {
            color: #67c23a;
          }

          .log-message {
            color: #67c23a;
          }
        }

        &.error {
          .log-type {
            color: #f56c6c;
          }

          .log-message {
            color: #f56c6c;
          }
        }

        &.warning {
          .log-type {
            color: #e6a23c;
          }

          .log-message {
            color: #e6a23c;
          }
        }

        &.info {
          .log-type {
            color: #409eff;
          }

          .log-message {
            color: #b0b0b0;
          }
        }
      }

      .no-logs {
        text-align: center;
        color: #606266;
        padding: 50px 0;
        font-size: 14px;
      }

      &::-webkit-scrollbar {
        width: 8px;
      }

      &::-webkit-scrollbar-track {
        background: #2a2a2a;
      }

      &::-webkit-scrollbar-thumb {
        background: #555;
        border-radius: 4px;

        &:hover {
          background: #666;
        }
      }
    }
  }
}
</style>

